#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>

#define SERVER_PORT 666

void *thread_handleRequest(void *arg);

int main(void)
{

    int sock; //准备传输通道
    struct sockaddr_in server_addr;

    // 1.创建通道
    sock = socket(AF_INET, SOCK_STREAM, 0);

    // 2.清空标签，写上自己的地址和端口号
    bzero(&server_addr, sizeof(server_addr));

    server_addr.sin_family = AF_INET;                //选择协议族IPV4
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //监听本地所有IP地址
    server_addr.sin_port = htons(SERVER_PORT);       //绑定端口号

    //实现标签贴到管道出口
    bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));

    //开始接收信息
    listen(sock, 128);

    //万事俱备，只等来信
    printf("等待客户端的连接\n");

    int done = 1;

    while (done)
    {
        struct sockaddr_in client;
        int client_sock, len;
        char client_ip[64];

        socklen_t client_addr_len;
        client_addr_len = sizeof(client);
        client_sock = accept(sock, (struct sockaddr *)&client, &client_addr_len);

        //打印客服端IP地址和端口号
        printf("client ip: %s\t port : %d\n",
               inet_ntop(AF_INET, &client.sin_addr.s_addr, client_ip, sizeof(client_ip)),
               ntohs(client.sin_port));

        //启动线程，完成和和客户端的交互
        {
            pthread_t tid;
            int *ptr_int = NULL;
            int err = 0;

            ptr_int = (int *)malloc(sizeof(int));
            *ptr_int = client_sock;

            if (err = pthread_create(&tid, NULL, thread_handleRequest, (void *)ptr_int))
            {
                fprintf(stderr, "Can't create thread, reason: %s\n", strerror(errno));
                if (ptr_int)
                    free(ptr_int);
            }
        }
    }
    close(sock);
    return 0;
}

void *thread_handleRequest(void *arg)
{
    int client_sock = *(int *)arg;
    char buf[256];
    int i = 0;

    int len = read(client_sock, buf, sizeof(buf) - 1);
    buf[len] = '\0';
    printf("receive[%d]: %s\n", len, buf);

    //转换成大写
    for (i = 0; i < len; i++)
    {
        buf[i] = toupper(buf[i]);
    }

    len = write(client_sock, buf, len);

    printf("finished. len: %d\n", len);
    close(client_sock);

    if (arg)
        free(arg);
}
